package brcl.utils;

import brcl.constant.BrclConstant;
import cn.hyperchain.sdk.account.Account;
import cn.hyperchain.sdk.account.Algo;
import cn.hyperchain.sdk.common.utils.Decoder;
import cn.hyperchain.sdk.common.utils.FileUtil;
import cn.hyperchain.sdk.common.utils.InvokeDirectlyParams;
import cn.hyperchain.sdk.exception.RequestException;
import cn.hyperchain.sdk.provider.DefaultHttpProvider;
import cn.hyperchain.sdk.provider.HttpProvider;
import cn.hyperchain.sdk.provider.ProviderManager;
import cn.hyperchain.sdk.response.ReceiptResponse;
import cn.hyperchain.sdk.service.ContractService;
import cn.hyperchain.sdk.service.ServiceManager;
import cn.hyperchain.sdk.transaction.Transaction;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;

/**
 * HVM工具类
 *
 * @version v1.0
 * @className: HvmUtils
 * @author: heyiheng
 * @date: 2021-04-16 16:49
 */
@Component
public class HvmUtils {

	@Value("${default.url}")
	private String url;
	@Value("${default.jarPath}")
	private String jarPath;

	/**
	 * 创建钱包，生成钱包文件
	 * @return
	 */
	public Account createAccount(){
		DefaultHttpProvider provider = new DefaultHttpProvider.Builder().setUrl(url).build();
		ProviderManager providerManager = ProviderManager.createManager(provider);
		Account account = ServiceManager.getAccountService(providerManager).genAccount(Algo.SMRAW);

		// 将钱包生成文件
		String jsonFile = JsonToListBeanUtils.creatNewJsonFile(account.toJson());
		System.out.println(jsonFile);
		return account;

	}

	public ReceiptResponse createContract() throws IOException, RequestException {
		DefaultHttpProvider provider = new DefaultHttpProvider.Builder().setUrl(url).build();
		ProviderManager providerManager = ProviderManager.createManager(provider);
		ContractService contractService = ServiceManager.getContractService(providerManager);
		InputStream payload = FileUtil.readFileAsStream(jarPath);
		Transaction transaction = new Transaction.HVMBuilder(BrclConstant.CONTRACT_ADDRESS).deploy(payload).build();

		sign(transaction);
		return contractService.deploy(transaction).send().polling();
	}

	/**
	 * 建立链上链接
	 * @return
	 */
	public ProviderManager createProviderManager() {
		HttpProvider provider = new DefaultHttpProvider.Builder().setUrl(url).build();
		ProviderManager manager = ProviderManager.createManager(provider);
		System.out.println("provider:"+ provider.getStatus());
		System.out.println("provider:"+ provider.getUrl());
		return manager;
	}

	public HttpProvider createHttpProvider(){
		return new DefaultHttpProvider.Builder().setUrl(url).build();
	}

	public ContractService createContractService(){
		DefaultHttpProvider provider = new DefaultHttpProvider.Builder().setUrl(url).build();
		ProviderManager providerManager = ProviderManager.createManager(provider);
		return ServiceManager.getContractService(providerManager);
	}

	/**
	 * 签名
	 * @param transaction 签名交易
	 */
	public void sign(Transaction transaction){
		DefaultHttpProvider provider = new DefaultHttpProvider.Builder().setUrl(url).build();
		ProviderManager providerManager = ProviderManager.createManager(provider);
		transaction.sign(ServiceManager.getAccountService(providerManager).fromAccountJson(getUser()));
	}

	public String getUser(){
		String userCode = JsonToListBeanUtils.readFile(BrclConstant.PATH + "account.json");
		System.out.println(userCode);
		return userCode;
	}

	/**
	 * 发起交易
	 * @param params 交易参数
	 * @return
	 */
	public String trading(InvokeDirectlyParams params) throws RequestException {
		Transaction transaction = new Transaction.HVMBuilder(BrclConstant.ADDRESS).invokeDirectly(BrclConstant.CONTRACT_ADDRESS, params).build();
		sign(transaction);
		ReceiptResponse response = createContractService().invoke(transaction).send().polling();

		return Decoder.decodeHVM(response.getRet(),String.class);
	}
}
